package service

import (
	"context"
	"gomain/app/model"

	"github.com/gogf/gf/v2/frame/g"
)

var Menu = menuService{}

type menuService struct{}

// 获取菜单树
func (s *menuService) GetTree() ([]model.Menu, error) {
	var menus []model.Menu
	err := g.Model("menus").
		Where("status", 1).
		Where("visible", 1). // 只获取显示的菜单
		Order("sort asc").
		Scan(&menus)
	if err != nil {
		return nil, err
	}
	return s.buildTree(menus, 0, 0), nil
}

// 获取前端菜单数据
func (s *menuService) GetMenuTree() ([]g.Map, error) {
	menus, err := s.GetTree()
	if err != nil {
		g.Log().Error(context.Background(), "GetMenuTree error:", err)
		return nil, err
	}

	if len(menus) == 0 {
		return []g.Map{}, nil
	}

	return s.convertToMenuTree(menus), nil
}

// 转换为前端菜单格式
func (s *menuService) convertToMenuTree(menus []model.Menu) []g.Map {
	var result []g.Map
	for _, menu := range menus {
		if menu.Type != 2 { // 按钮不显示在菜单中
			item := g.Map{
				"id":    menu.Id,
				"title": menu.Title,
				"icon":  menu.Icon,
				"type":  menu.Type,
			}
			if menu.Type == 1 { // 菜单类型
				item["href"] = menu.Path
				item["openType"] = "_component"
			}
			if len(menu.Children) > 0 {
				item["children"] = s.convertToMenuTree(menu.Children)
			}
			result = append(result, item)
		}
	}
	return result
}

// 构建菜单树
func (s *menuService) buildTree(menus []model.Menu, parentId int, depth ...int) []model.Menu {
	var tree []model.Menu
	// 获取当前深度
	currentDepth := 0
	if len(depth) > 0 {
		currentDepth = depth[0]
	}
	// 限制最大递归深度为5层
	if currentDepth > 5 {
		return tree
	}

	for _, menu := range menus {
		if menu.ParentId == parentId {
			// 先创建一个新的menu副本，避免修改原始数据
			newMenu := menu
			// 递归获取子菜单，深度+1
			children := s.buildTree(menus, menu.Id, currentDepth+1)
			// 只有在有子菜单时才设置Children字段
			if len(children) > 0 {
				newMenu.Children = children
			}
			tree = append(tree, newMenu)
		}
	}
	return tree
}

// 获取菜单列表
func (s *menuService) List() ([]model.Menu, error) {
	var menus []model.Menu
	err := g.Model("menus").
		Order("sort asc").
		Scan(&menus)
	return menus, err
}

// 添加菜单
func (s *menuService) Add(menu *model.Menu) error {
	_, err := g.Model("menus").Data(menu).Insert()
	return err
}

// 更新菜单
func (s *menuService) Update(menu *model.Menu) error {
	_, err := g.Model("menus").Data(menu).Where("id", menu.Id).Update()
	return err
}

// 删除菜单
func (s *menuService) Delete(id int) error {
	_, err := g.Model("menus").Where("id", id).Delete()
	return err
}
